import React, { useState, useRef, useLayoutEffect } from 'react'
import styles from './index.module.scss'
import MyNavBar from '@/components/MyNavBar'
import { getCurrentCity } from '@/utils/city'
import { Toast } from 'antd-mobile'
import { getMapOverlay, getHoustListById } from '@/api/map'
import classNames from 'classnames'
import HouseItem from '@/components/HouseItem'

const BMap = window.BMap
// 覆盖物的样式：
const labelStyle = {
  cursor: 'pointer',
  border: '0px solid rgb(255, 0, 0)',
  padding: '0px',
  whiteSpace: 'nowrap',
  fontSize: '12px',
  color: 'rgb(255, 255, 255)',
  textAlign: 'center'
}

function Map () {
  const mapRef = useRef()

  const [isShow, setIsShow] = useState(false)
  const [houseList, setHouseList] = useState(null)

  const initMap = async () => {
    //1、获取当前定位城市名称
    const { label, value } = await getCurrentCity()
    // 创建地址解析器实例
    const myGeo = new BMap.Geocoder()
    // 将地址解析结果显示在地图上，并调整地图视野
    myGeo.getPoint(
      label,
      point => {
        if (point) {
          const map = new BMap.Map('container')
          const top_right_navigation = new BMap.NavigationControl({
            anchor: window.BMAP_ANCHOR_BOTTOM_RIGHT,
            type: window.BMAP_NAVIGATION_CONTROL_SMALL
          })
          map.addControl(top_right_navigation)
          map.centerAndZoom(point, 11)
          mapRef.current = map

          // 添加touch事件
          map.addEventListener('touchmove', () => {
            setIsShow(false)
          })

          // 渲染覆盖物
          renderOverlays(value)
        }
      },
      label
    )
  }

  // 获取点击覆盖物之后，下一级覆盖物的形状和缩放级别
  const getRenderTypeAndNextZoom = () => {
    const currentZoom = mapRef.current.getZoom()

    let type = 'circle'
    let nextZoom = 13
    if (currentZoom > 10 && currentZoom < 12) {
      type = 'circle'
      nextZoom = 13
    } else if (currentZoom > 12 && currentZoom < 14) {
      type = 'circle'
      nextZoom = 15
    } else if (currentZoom > 14) {
      type = 'rect'
    }

    return { type, nextZoom }
  }

  // 渲染一二级覆盖物(圆形覆盖物)
  const renderCircleOverlay = (
    { coord: { latitude, longitude }, count, label: name, value: id },
    nextZoom
  ) => {
    const point = new BMap.Point(longitude, latitude)
    const opts = {
      position: point, // 指定文本标注所在的地理位置
      offset: new BMap.Size(-35, -35) //设置文本偏移量
    }
    const label = new BMap.Label('', opts) // 创建文本标注对象
    label.setStyle(labelStyle)
    label.setContent(`
      <div class="${styles.bubble}">
        <p class="${styles.name}">${name}</p>
        <p class="${styles.name}">${count}套</p>
      </div>
    `)

    // 添加点击事件
    label.addEventListener('click', () => {
      setTimeout(() => {
        // 移除覆盖物
        mapRef.current.clearOverlays()
      }, 0)
      // 更改中心点和缩放级别
      mapRef.current.centerAndZoom(point, nextZoom)
      // 加载下一级数据
      renderOverlays(id)
    })

    mapRef.current.addOverlay(label)
  }

  // 渲染三级覆盖物
  const renderRectOverlay = ({
    coord: { latitude, longitude },
    count,
    label: name,
    value: id
  }) => {
    const point = new BMap.Point(longitude, latitude)
    var opts = {
      position: point, // 指定文本标注所在的地理位置
      offset: new BMap.Size(-50, -20) //设置文本偏移量
    }
    const label = new BMap.Label('', opts) // 创建文本标注对象
    label.setStyle(labelStyle)
    label.setContent(`
      <div class="${styles.rect}">
        <span class="${styles.housename}">${name}</span>
        <span class="${styles.housenum}">${count}</span>
        <i class=${styles.arrow}/>
      </div>
    `)
    label.addEventListener('click', e => {
      if (!e.changedTouches || !e.changedTouches[0]) return
      const { clientX, clientY } = e.changedTouches[0]
      const moveX = window.screen.width * 0.5 - clientX
      const moveY = window.screen.height / 2 - clientY - 330 / 2
      // 把点击的小区移动到地图中间
      mapRef.current.panBy(moveX, moveY)
      // 发请求，获取小区的房源列表
      getHouseListData(id)
    })
    mapRef.current.addOverlay(label)
  }

  const getHouseListData = async id => {
    Toast.loading('数据加载中...', 0)
    const res = await getHoustListById(id)
    Toast.hide()
    setHouseList(res.data.body.list)
    setIsShow(true)
  }

  const renderOverlays = async id => {
    Toast.loading('数据加载中...', 0)
    const res = await getMapOverlay(id)
    Toast.hide()

    // 对数据进行处理
    const { type, nextZoom } = getRenderTypeAndNextZoom()
    res.data.body.forEach(item => {
      if (type === 'circle') {
        renderCircleOverlay(item, nextZoom)
      } else {
        renderRectOverlay(item)
      }
    })
  }

  useLayoutEffect(() => {
    initMap()
  }, [])

  // 渲染房源列表
  const renderHouseList = () => {
    return (
      <div className={classNames(styles.houseList, { [styles.show]: isShow })}>
        <div className={styles.titleWrap}>
          <h1 className={styles.listTitle}>房屋列表</h1>
          <a href='#/houselist' className={styles.titleMore}>
            更多房源
          </a>
        </div>
        <div className={styles.houseItems}>
          {houseList.map(item => {
            return <HouseItem key={item.houseCode} {...item} />
          })}
        </div>
      </div>
    )
  }

  return (
    <div className={styles.map}>
      <MyNavBar>地图找房</MyNavBar>
      <div id='container'></div>
      {houseList && renderHouseList()}
    </div>
  )
}

export default Map
